package opc.read.sycread;

import com.alibaba.fastjson.JSON;
import opc.read.utils.MyCopyOnWriteMap;
import opc.read.utils.ReadHostProt;
import opc.read.utils.WriterFile;
import org.openscada.opc.lib.common.ConnectionInformation;
import org.openscada.opc.lib.da.Group;
import org.openscada.opc.lib.da.Item;
import org.openscada.opc.lib.da.Server;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @Description:  用simu软件 建立的四个信号，这里使用同步读取
 * @author: liyuan
 * @data 2021-01-06 10:21
 */
public class ByDemoRead {
    public static void main(String[] args) throws IOException {
        ByDemoRead.DemoAPI();
    }
    public static void DemoAPI() throws IOException {

        Map<String, String> dataSources = ReadHostProt.loadFile();

        final ConnectionInformation ci = new ConnectionInformation();
        final SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        ci.setHost(dataSources.get("host"));
        ci.setDomain(dataSources.get("domain"));
        ci.setUser(dataSources.get("user"));
        ci.setPassword(dataSources.get("password"));
        ci.setClsid(dataSources.get("clsid"));
        final Map<String, Map<String, Item>> result = new LinkedHashMap<String, Map<String, Item>>();
//        final Map<String, Object> resultNew = new LinkedHashMap<String, Object>();
        final MyCopyOnWriteMap<String, Object> resultNew = new MyCopyOnWriteMap<String, Object>(new LinkedHashMap<String, Object>());
        final Server server = new Server(ci, Executors.newSingleThreadScheduledExecutor());
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
//        final AutoReconnectController autoReconnectController = new AutoReconnectController(server);
        try {

            /***  connect to server  ***/
//            autoReconnectController.connect();
            server.connect();
            int size = Integer.parseInt(dataSources.get("len"));
//            final AccessBase access = new SyncAccess(server, 1000);
//            final AccessBase access = new Async20Access(server, 1000,false);
            for (int i = 0; i < size; i++) {
                //设置group对象
                String groupName = dataSources.get("deviceName" + i);
                /***
                 *  构造组信号集合“：groupName {	"CST28214": "", 	"SP28214_RD": ""}
                 */
                String[] split = dataSources.get("deviceName" + i + ".deviceItem").split(",");
                Group group = null;
                group = server.addGroup(groupName);
                group.setActive(true);
                Map<String, Item> itemMap = group.addItems(split);
                result.put(groupName, itemMap);
                LinkedHashMap<String, Object> tmp = new LinkedHashMap<String, Object>();
                for (int j = 0; j < split.length; j++) {
                    tmp.put(split[j], null);
                }
                resultNew.put(groupName, tmp);
            }
            //首先遍历读一遍
            resultNew.put("date", System.currentTimeMillis());
            for (final String groupName : result.keySet()) {
                Map<String, Item> itemMap = result.get(groupName);
                //组内部的读取信号
                for (Map.Entry<String, Item> map : itemMap.entrySet()) {
                    if (map.getValue() instanceof Item) {
                        Item item = map.getValue();
                        Object object = item.read(false).getValue().getObject();
                        Short quality = item.read(false).getQuality();
                        if (quality < 192) object = null; // 当信号质量值小于192的时候，表示该信号有问题，该信号值赋值为null
                        ((Map<String, Object>) resultNew.get(groupName)).put(item.getId(), object);  // 去掉xianhe.设备 1., 只留下需要的信号名
                    }
                }
            }

            /*** 新开线程执行写读取操作 **/
            scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
                @Override
                public void run() {
                    String s = JSON.toJSONString(resultNew);
                    System.out.println("--json---");
                    System.out.println(s);
                    WriterFile.writeTxtFile(s, new File("d:/ProDataAccess/xianhe/data/file1/" + formatter.format(new Date()) + ".txt"), "utf-8");
                }
                //单位是毫秒
            }, 1000, 1000, TimeUnit.MILLISECONDS);
            /*** 主线程在一直读取  ***/
            while (true) {
                resultNew.put("date", System.currentTimeMillis());
                /***  单个组和多个信号  **/
                for (final String groupName : result.keySet()) {
                    Map<String, Item> itemMap = (Map<String, Item>) result.get(groupName);
                    Map<String, Object> resultItemMap = new HashMap<String, Object>();
                    for (Map.Entry<String, Item> map : itemMap.entrySet()) {
                        if (map.getValue() instanceof Item) {
                            Item item = map.getValue();
                            Object object = item.read(false).getValue().getObject();
                            resultItemMap.put(item.getId(), object);
                        }
                    }
                    resultNew.put(groupName, resultItemMap);

                }

//                  {
//                    StringBuilder builder = new StringBuilder();
////                    builder.append("cd D:\\ProDataAccess\\xianhe\\target\\classes");
////                    builder.append("java opc.read.App");
////                    builder.append("cd D:\\ProDataAccess\\xianhe\\out\\artifacts\\xianhe_jar\n");
//                    builder.append("java -Djava.io.tmpdir=d:/ProDataAccess/xianhe/lib -jar xianhe.jar");
//                    String s = builder.toString();
//                    File path = new File("D:\\ProDataAccess\\xianhe\\out\\artifacts\\xianhe_jar");
//                    Process process = Runtime.getRuntime().exec(builder.toString(), null, path);
//                    process.destroy();
//                    Runtime.getRuntime().exit(2);
//                }
            }

//            access.unbind();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
